/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package babyroom

import javafx.scene.image._
import javafx.scene.input._
import javafx.scene.layout._
import javafx.geometry._
import javafx.scene._
import EventLambdar._

class ImagedPaneBuilder(val img: Image, val cell: GridCell){
  def build(): GridPane = {
    val y = 0
    val x = 0
    val pane = new GridPane
    cell.addTo(pane, x, img.widthProperty.get, y, img.heightProperty.get, img)
    
    pane.onScrollProperty.set((e: ScrollEvent) => {
        if(e.getDeltaY > 0){
          pane.setScaleX(pane.getScaleX + 0.1)
          pane.setScaleY(pane.getScaleY + 0.1)
        }
        else if(e.getDeltaY < 0){
          if(pane.getScaleX >= 0.5){
            pane.setScaleX(pane.getScaleX - 0.1)
            pane.setScaleY(pane.getScaleY - 0.1)
          }else()
        }else()})
    
    ImagedPaneBuilder.panesCreated = pane :: ImagedPaneBuilder.panesCreated
    pane
  }
}

object ImagedPaneBuilder{
  var panesCreated: List[GridPane] = List.empty[GridPane]
  val debug = {
    var b = true;
    () => {
      panesCreated.foreach(pane => pane.gridLinesVisibleProperty.set(b))
      b = !b
    }
  }
  def apply(img: Image, cell: GridCell): GridPane = new ImagedPaneBuilder(img, cell).build
}

trait GridCell{
  def addTo(pane: GridPane,  x: Double, w: Double, y: Double, h: Double, img: Image): Double 
}

trait RowCell extends GridCell
object RowCell{
  def apply(height: Double, inserts: Node*): RowCell = new LeafRowCell(height, inserts: _*)
  def apply(height: Double, column: ColumnCell, columns: ColumnCell*): RowCell = new BranchRowCell(height, column, columns: _*)
}

trait ColumnCell extends GridCell
object ColumnCell{
  def apply(width: Double, inserts: Node*): ColumnCell = new LeafColumnCell(width, inserts: _*)
  def apply(width: Double, row: RowCell, rows: RowCell*): ColumnCell = new BranchColumnCell(width, row, rows: _*)
}

class LeafRowCell(val height: Double, val inserts: Node*) extends RowCell{
  override def addTo(pane: GridPane,  x: Double, w: Double, y: Double, h: Double, img: Image): Double = {
    val r = new RowConstraints
    r.maxHeightProperty.set(height)
    r.minHeightProperty.set(height)
    val view = new ImageView(img)
    view.viewportProperty.set(new Rectangle2D(x, y, w, height))
    val index = pane.getRowConstraints.size
    pane.getRowConstraints.add(r)
    pane.addRow(index, view)
    pane.addRow(index, inserts: _*)
    height
  }
}

class BranchRowCell(val height: Double, val column: ColumnCell, val columns: ColumnCell*) extends RowCell{
  override def addTo(pane: GridPane,  x: Double, w: Double, y: Double, h: Double, img: Image): Double = {
    val r = new RowConstraints
    r.maxHeightProperty.set(height)
    r.minHeightProperty.set(height)
    val index = pane.getRowConstraints.size
    pane.getRowConstraints.add(r)    
    val nestPane = new GridPane
    ImagedPaneBuilder.panesCreated = nestPane :: ImagedPaneBuilder.panesCreated
    pane.addRow(index, nestPane)
    var sum = column.addTo(nestPane, x, w, y, height, img)
    for(i <- 0 until columns.length){
      sum += columns(i).addTo(nestPane, x + sum, w, y, height, img)
    }
    if(sum < w)
      sum += ColumnCell(w - sum).addTo(nestPane, x + sum, w, y, height, img)
    height
  }
}

class LeafColumnCell(val width: Double, val inserts: Node*) extends ColumnCell{
  override def addTo(pane: GridPane,  x: Double, w: Double, y: Double, h: Double, img: Image): Double = {
    val c = new ColumnConstraints
    c.maxWidthProperty.set(width)
    c.minWidthProperty.set(width)
    val view = new ImageView(img)
    view.viewportProperty.set(new Rectangle2D(x, y, width, h))
    val index = pane.getColumnConstraints.size
    pane.getColumnConstraints.add(c)
    pane.addColumn(index, view)
    pane.addColumn(index, inserts: _*)
    width
  }
}
  
class BranchColumnCell(val width: Double, val row: RowCell, val rows: RowCell*) extends ColumnCell{
  override def addTo(pane: GridPane,  x: Double, w: Double, y: Double, h: Double, img: Image): Double = {
    val c = new ColumnConstraints
    c.maxWidthProperty.set(width)
    c.minWidthProperty.set(width)
    val index = pane.getColumnConstraints.size
    pane.getColumnConstraints.add(c)
    val nestPane = new GridPane
    ImagedPaneBuilder.panesCreated = nestPane :: ImagedPaneBuilder.panesCreated
    pane.addColumn(index, nestPane)
    var sum = row.addTo(nestPane, x, width, y, h, img)
    for(i <- 0 until rows.length){
      sum += rows(i).addTo(nestPane, x, width, y + sum, h, img)
    }
    if(sum < h){
      sum += RowCell(h - sum).addTo(nestPane, x, width, y + sum, h, img)
    }
    width
  }
}
